#include <time.h>

#ifndef BASE_LIB_INCLUDE_LIBFLOW_H
#define BASE_LIB_INCLUDE_LIBFLOW_H


/* Maximum flow name length
 * Maximum length of a task in a flow
 */
#define MAX_FLOW_NAME_LEN 256
#define MAX_TASK_NAME_LEN 256


#ifdef	__cplusplus
extern "C"
{
#endif

typedef struct task{

	char taskName[MAX_TASK_NAME_LEN];

	time_t start;
	time_t end;

    /**<
        1 means the task is done sucessfully
        0 means the task is failed*/
    int revCode;

    /**<
        nextLen indicates how many following tasks there are*/
    int childNum;

    /*Child position in the storage arry of a flow*/
    int *childposes;

    /**<
        p_data void *
        the structure which will be handled by task plugins.
        Task plugin needs to malloc p_data in initTask() and free it in freeTask() after the task is done or failed.
     */
    void *p_data;

    /**<
     1 means Required If the task fails, the workflow will fail immediately
     0 means optional If the task fails, the workflow will skip it and execute next tasks.
     */
    int required;

    /**<
        hkey (short for hashkey) is used to indicate which plugin will handle the p_data
         It can be a process handling call back function or a file_arriving call back function
    */
    char * hkey;



    /**<
        errMessage stores the error message if the task goes wrong.
        task plugin needs set it up in execTask
        */
    char *errMessage;

    /**<
        waitCount indicates
        the count of how many conditions the task should meet in order to get triggered. */
    int waitCount;

#ifdef OS_LINUX
    char * shell;
    char ** sys_variables;
#endif

    char *errFile;
    //char *inFile;
    char *outFile;

    char * run_uname;

}task;

typedef long flowInt;


/*
 * failSign list (Refer to the member of task below)
 */
#define REQUIRED 0
#define REQUISITE 1
#define OPTIONAL 2

typedef struct flow{

	/* Flowid is unique for sure. Two flows will never ever have a same flow id.
	 * */

	flowInt flowid;
	char flowName[MAX_FLOW_NAME_LEN];

	time_t subTime;
	time_t startTime;
	time_t endTime;

	/* How many tasks are there in the flow
	 * */
	unsigned int taskLen;

	/*
	 * Tasks that are in the flow. Tasks are stored based on N-Tree algorithm (implemented
	 * with a array)
	 */
	task* t;

	/* failSign indicates how the program determines the flow fails/succeeds.
	 *
	 *  	0 means the flow only succeeds if all tasks in the flow succeed.
	 *  	Any task failure will cause the flow to fail immediately.
	 *
	 *  	1 means the flow will fail if the major tasks that are marked fail.
	 *  	Any major task failure will cause the flow to fail immediately.
	 *  	All major tasks success will make the whole flow success.
	 * */
	int failSign;

	unsigned int majorNum;
	task **majors;

/*
	 *  The triggerEvents which can trigger the flow to run.
	triggerEvent trEvent;
	 * The controlEvents which can trigger sth to run under some special circumstances.
	controlEvent ctlEvent;
*/


}flow;

#ifdef	__cplusplus
}
#endif

#endif
